/*
 * ViewUsersHandlers.java
 * 
 * @version 1.0, Apr 27, 2011
 * CS 2340 Team 10: Cyberdyne Systems
 */
package edu.gatech.oad.cyberdoc.domain.action;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import edu.gatech.oad.cyberdoc.domain.Admin;
import edu.gatech.oad.cyberdoc.domain.Doctor;
import edu.gatech.oad.cyberdoc.domain.Staff;
import edu.gatech.oad.cyberdoc.domain.User;
import edu.gatech.oad.cyberdoc.domain.filter.Filter;
import edu.gatech.oad.cyberdoc.domain.filter.TypeFilter;

/**
 * Handles view users actions by patients.
 * 
 * @author John Girata
 * @version 1.0, April 27, 2011
 */
public class ViewUsersHandler extends ActionHandler {

	/**
	 * The action code this ActionHandler corresponds to.
	 */
	public static final String ACTION_CODE;

	/**
	 * The logger for this class.
	 */
	private static final Logger LOG;

	static {
		ACTION_CODE = "view_users";
		LOG = Logger.getLogger("edu.gatech.oad.cyberdoc.action."
				+ "ViewUsersHandler");
	}

	/**
	 * Registers this handler with the classes through which it can respond to
	 * request.
	 */
	public ViewUsersHandler() {
		Staff.addActionHandler(ACTION_CODE, this);
		Doctor.addActionHandler(ACTION_CODE, this);
		Admin.addActionHandler(ACTION_CODE, this);
	}

	/**
	 * Reverts the registrations made by the constructor.
	 */
	@Override
	public void destroy() {
		Staff.removeActionHandler(this);
		Doctor.removeActionHandler(this);
		Admin.removeActionHandler(this);
	}

	/**
	 * Handles view user commands by returning all users the source user is
	 * allowed to see.
	 * 
	 * This method does not expect any fields in the command.
	 * 
	 * This method will return the following fields:
	 * 
	 * users: a JSONArray of JSONObjects representing users
	 * 
	 * next: The next panel to show
	 * 
	 * @param source
	 *            The user that called this method
	 * @param command
	 *            The command encoding the action
	 * @return The result of performing this action
	 * @throws ActionHandleException
	 *             If a required field does not exist in the command, or if the
	 *             usernames given for the patient and doctor are invalid
	 */
	@Override
	public JSONObject handle(User source, JSONObject command)
			throws ActionHandleException {
		LOG.info("Handling view_users action");

		if (source == null) {
			final String message = "Source user cannot be null";
			LOG.severe(message);
			throw new ActionHandleException(new NullPointerException(message));
		}

		final JSONObject response = new JSONObject();
		final Filter[] filters;

		try {
			if (source instanceof Admin) {
				LOG.info("User is an Admin; listing all users");
				filters = new Filter[0];
			} else {
				LOG.info("User is not an Admin; listing only patients");
				filters = new Filter[] { new TypeFilter(
						Class.forName("edu.gatech.oad.cyberdoc.domain.Patient")) };
			}

			final List<User> users = User.filterUsers(filters);
			final JSONArray array = new JSONArray();

			for (User user : users) {
				array.put(user.toJSONObject());
			}

			response.put("users", array);
			response.put("next", "view_users");
		} catch (ClassNotFoundException e) {
			LOG.log(Level.SEVERE, "Patient class not found", e);
			throw new ActionHandleException(e);
		} catch (JSONException e) {
			LOG.log(Level.SEVERE, "Unexpected JSONException.", e);
			throw new ActionHandleException(e);
		}

		return response;
	}

	/**
	 * Returns a string representation of this class.
	 * 
	 * @return A string representation of this class
	 */
	@Override
	public String toString() {
		return "ViewUsersHandler []";
	}
}
